using System;

namespace AreaGenerator
{
	public class Wall
	{
		public Node n1;
		public Node n2;
		
		public int keyID = 0;
		
		public WallType type = WallType.defaultType;
		
		public bool mirrored = false;
		
		public Wall(Node n1, Node n2){
			if (n1.isAdjacent(n2)){
				this.n1 = n1;
				this.n2 = n2;
			}
			else
			{
				Console.WriteLine("pas adjacent");
			}
		}
		
		public bool containsNode(Node n){
			return n1.Equals(n) || n2.Equals(n);
		}
		
		public void setWallType(Room leftRoom, Room rightRoom){
			if (leftRoom == null || !leftRoom.isEnabled()) {
				if (rightRoom.isDeep()) type = WallType.depth;
				else type = WallType.wall_default;
				
			} else if (rightRoom == null || !rightRoom.isEnabled()) {
				if (leftRoom.isDeep()) type = WallType.depth;
				else type = WallType.wall_default;
				
			} else if (!leftRoom.isDeep() && !rightRoom.isDeep ()){
				if(leftRoom.isHigh() != rightRoom.isHigh()){
					type = WallType.edge;
					if (leftRoom.isHigh()) this.mirror();
				} else {
					type = WallType.wall_default;
				}
			} else if (leftRoom.isDeep() && rightRoom.isDeep ()){
				type = WallType.depth;
			} else {
				if (rightRoom.isDeep()){
					if(rightRoom.isHigh()) type = WallType.wall_depth_high;
					else type = WallType.wall_depth;
				}
				if (leftRoom.isDeep()) {
					if(leftRoom.isHigh()) type = WallType.wall_depth_high;
					else type = WallType.wall_depth;
					this.mirror();
				}
			}
		}
		
		public void setDoorType(Room leftRoom, Room rightRoom){
			if (!leftRoom.isDeep() && !rightRoom.isDeep ()){
				if(leftRoom.isHigh() != rightRoom.isHigh()){
					type = WallType.stairs;
					if (leftRoom.isHigh()) this.mirror();
				} else {
					if (leftRoom.isHigh()) type = WallType.doorway_high;
					else type = WallType.doorway;
				}
			} else if (leftRoom.isDeep() && rightRoom.isDeep ()){
				if(leftRoom.isHigh() != rightRoom.isHigh()){
					type = WallType.stairs_bridge;
					if (rightRoom.isHigh()) this.mirror();
				} else {
					if (leftRoom.isHigh()) type = WallType.bridge_high;
					else type = WallType.bridge;
				}
			} else if (leftRoom.isHigh() == rightRoom.isHigh()){
				type = WallType.bridge_doorway;
				if (leftRoom.isHigh()) type = WallType.bridge_doorway_high;
				else type = WallType.bridge_doorway;
				if (leftRoom.isDeep()) this.mirror();
			} else {
				if ((leftRoom.isDeep() && leftRoom.isHigh()) || (rightRoom.isDeep() && rightRoom.isHigh())){
					type = WallType.stairs_from_depth;
					if (leftRoom.isHigh()) this.mirror();
				}
				else {
					type = WallType.stairs_to_depth;
					if (rightRoom.isHigh()) this.mirror();
				}
			}
		}
		
		public override bool Equals(Object wall){
			Wall w = wall as Wall;
			return ((this.n1.Equals(w.n1) && this.n2.Equals(w.n2)) || 
					(this.n1.Equals(w.n2) && this.n2.Equals(w.n1)));
		}
		
		public Orientation getOrientation(){
			if (n1.east != null && n2.Equals(n1.east)) return Orientation.east;
			if (n1.south != null && n2.Equals(n1.south)) return Orientation.south;
			if (n1.west != null && n2.Equals(n1.west)) return Orientation.west;
			if (n1.north != null && n2.Equals(n1.north)) return Orientation.north;
			UnityEngine.Debug.Log ("Orientation, this shouldn't happen");
			return Orientation.east;
		}
		
		public Orientation getOppositeOrientation(){
			if (n1.east != null && n2.Equals(n1.east)) return Orientation.west;
			if (n1.south != null && n2.Equals(n1.south)) return Orientation.north;
			if (n1.west != null && n2.Equals(n1.west)) return Orientation.east;
			if (n1.north != null && n2.Equals(n1.north)) return Orientation.south;
			UnityEngine.Debug.Log ("Orientation, this shouldn't happen");
			return Orientation.east;
		}
		
		public override int GetHashCode(){
			return n1.GetHashCode() + n2.GetHashCode();	
		}
		
		public override String ToString(){
			return "("+n1+"|"+n2+")";
		}
		
		public void mirror(){
			mirrored = !mirrored;
		}
		
		public bool isDoor(){
			return type >= WallType.doorway;
		}
		
		public bool isNoWall(){
			return type == WallType.defaultType;
		}
	}
	
	public enum WallType{
		defaultType,
		wall_default,
		edge,
		depth,
		wall_depth,
		wall_depth_high,
		doorway,
		doorway_high,
		stairs,
		stairs_bridge,
		stairs_to_depth,
		stairs_from_depth,
		bridge,
		bridge_high,
		bridge_doorway,
		bridge_doorway_high
	}
	
	public enum Orientation{
		east,
		south,
		west,
		north
	}
}

